
// File:			R2.cpp
// Authors:			Richard Burris, Joshua Douty
// Purpose:			R2 work file
// Version:        	6.0
// Date:			11/03/2011


#include "mpx_supt.h"
//#include "R1.h"
#include "R2.h"
#include "R3.h"
#include "R4.h"
#include "R6.h"
//#include "COMHAND.h"

#include <string.h>
#include <stdlib.h>
#include <direct.h>


//Currently Operating Process
extern PCB_Pointer CurrOP;

extern int size;
extern char * buf;
//queues
extern PCB_Pointer Running;
extern PCB_Pointer Blocked;
extern PCB_Pointer Ready;
extern PCB_Pointer SuspReady;
extern PCB_Pointer SuspBlocked;


/*
	Procedure: allocate_PC
	Purpose: Allocate a space for the PCB
	Parameters: Non
	Return value: PCB_Pointer
	Calls:	sys_alloc_mem

	Globals: none

	Errors: none
*/
PCB_Pointer allocate_PCB(){
	PCB_Pointer process;
	process = (PCB*)(sys_alloc_mem(sizeof(Proc_Con_Block)));
	process->sBase = (unsigned char*)sys_alloc_mem(STACKSIZE*sizeof(unsigned char));
	process->sTop = process->sBase + STACKSIZE- sizeof(context);
	return process;
}//end allocate_PCB
   

/*
	Procedure: setNull
	Purpose: Sets values to NULL
	Parameters: None
	Return value: None
	Calls:	none
	Globals: 	Blocked
				Ready
				SuspReady
				SuspBlocked
	Errors: none
*/
void setNull(){
	Blocked = NULL;
	Ready = NULL;
	SuspReady = NULL;
	SuspBlocked = NULL;
}
	

/*
	Procedure: freePCB
	Purpose: Frees memory from the PCB
	Parameters: PCB_Pointer
	Return value: int
	Calls: sys_free_mem
	Globals: none
	Errors: none
*/   
int freePCB(PCB_Pointer pro){
	int ret = sys_free_mem(pro->sTop);
	sys_free_mem(pro->sBase);
	sys_free_mem(pro->loadAddr);
	ret = sys_free_mem(pro);
	return ret;
}//end free_PCB


/*
	Procedure: findPCB
	Purpose: Finds a particular PCB
	Parameters: char*
	Return value: PCB_Pointer
	Calls:	findQ
	Globals:	CurrOP
				Running
				Blocked
				Ready
				SuspReady
				SuspBlocked
	Errors: none
*/
PCB_Pointer findPCB(char* na1){
	PCB_Pointer process = findQ(CurrOP, na1);
	if(process == NULL){
		process = findQ(Running, na1);
		if(process==NULL){
			process = findQ(Blocked, na1);
			if(process == NULL){
				process = findQ(Ready, na1);
				if(process==NULL){
					process = findQ(SuspReady, na1);
					if(process==NULL){
						process = findQ(SuspBlocked, na1);
							if(process ==NULL){
								process = findQ(CurrOP, na1);
							}
					}
				}	
			}
		}
	}
	return process;
}//end findPCB()


/*
	Procedure: findQ
	Purpose: Finds a particular Queue
	Parameters:	PCB_Pointer
				char*
	Return value: PCB_Pointer
	Calls: 	findQ
	Globals: none
	Errors: none
*/
PCB_Pointer findQ(PCB_Pointer q, char* na){
	PCB_Pointer process = NULL;
	if(q==NULL){
		return NULL;
	}
	if(!stricmp(q->name, na)){
		process = q;
	}//end if
		else if (q->after !=NULL){
			process = findQ(q->after, na);
		}//end else if
	return process;
}//end findQ


/*
	Procedure: insertPCB
	Purpose: Insert a PCB into the ready or suspended ready Queue
	Parameters: PCB_Pointer
	Return value: None
	Calls: 	insert
			insertReady
	Globals: none
	Errors: none
*/
void insertPCB(PCB_Pointer pro){
	if(pro->stateR == READY){
		if(pro->stateS == SUSPEND){
			insert(&SuspReady, pro);
		}//end if
		else insertReady(pro);
	}//end if
			

	else if(pro->stateR == BLOCKED){
		if(pro->stateS == SUSPEND){
			insert(&SuspBlocked, pro);
		}//end if
		else insert(&Blocked, pro);
	}//end else if
	
	
	else if(pro->stateR == RUN){
		if(pro->stateS == SUSPEND){
			insert(&Running, pro);
		}
		else insert(&SuspReady, pro);
	}//end else if	
}//end insertPCB


/*
	Procedure: insert
	Purpose: Insert PCBs to the correct Queue
	Parameters:	PCB_Pointer*
				PCB_Pointer
	Return value: None
	Calls: 	none
	Globals: none
	Errors: none
*/
void insert(PCB_Pointer* q, PCB_Pointer pro){
	if((*q) == NULL){
		(*q) = pro;
		pro->after = NULL;
	} else{
		//Sets index to the head
		PCB_Pointer index = (*q);

		//Searchs until no PCBs after
		while(index->after !=NULL){
			index = index->after;
		}//end while
		
		//Sets the after to the PCB we want to input
		index->after = pro;
		//Sets the before to the list
		pro->before = index;
	}//end else
}//end insert()


/*
	Procedure: insertReady
	Purpose: Inserts a PCB into the ready queue
	Parameters: PCB_Pointer
	Return value: None
	Calls: 	none
	Globals: none
	Errors: none
*/
void insertReady(PCB_Pointer pro){
	
	PCB_Pointer prev;
	
	if(Ready ==NULL){//if the ready queue is empty/null
		Ready = pro;
	}//end if
	
	
	else{
		PCB_Pointer index = Ready;
		//we move through the queue and compare priorities until we meet a lower priority
		
		while((index->priority >= pro->priority) && (index->after!=NULL)){
			index = index->after;
		}//end while

		
		if(index->after !=NULL){//If not the last element
			prev = index->before;
		
			if(prev == NULL){//if the first element
				Ready=pro;
				pro->after = index;
				pro->before = NULL;
				index->before = pro;
			}//end if
			
			else{//somewhere in the middle
				pro->before = prev;
				prev->after = pro;
				index->before = pro;
				pro->after = index;
			}//end else 
		}//end if
		
		else{//if the index is at the last element
			if((index->priority) >= (pro->priority)){
				index->after = pro;
				pro->before = index;
				pro->after = NULL;
			}//end if

			
			else{
				prev = index->before;
				
				if(prev == NULL){//index is first and only element in the queue
					Ready = pro;
					pro->before = NULL;
					pro->after = index;
					index->before = pro;
				}//end first element
				
				else{//not the first element in the queue
					prev->after = pro;
					pro->before = prev;
					pro->after = index;
					index->before = pro;
				}//end else
			}//end else
		}//end else
		
	}//end else
}//end insertReady	


/*
	Procedure: removePCB
	Purpose: Removes a PCB from the Queue
	Parameters: PCB_Pointer
	Return value: None
	Calls: 	none
	Globals: none
	Errors: none
*/
void removePCB(PCB_Pointer pro){
	
    PCB_Pointer previous;
    PCB_Pointer next;

    //Get old neighbors
    previous = pro->before;
    next = pro->after;

    //Link old neighbors
    if(next!=NULL)
	next->before = previous;

    if(previous!=NULL)
	previous->after = next;

    //Set new heads
    if(pro == Blocked)
	Blocked = next;
    if(pro== SuspBlocked)
	SuspBlocked = next;
    if(pro == Ready)
	Ready = next;
    if(pro == SuspReady)
	SuspReady = next;
    
	

	pro->before = NULL;
	pro->after = NULL;
}//end removePCB


/*
	Procedure: setupPCB
	Purpose: Gets everything ready for the PCB
	Parameters: char*
				int
				int
	Return value: PCB_Pointer
	Calls: 	allocate_PCB
			removePCB
			freePCB
	Globals: none
	Errors: none
*/
PCB_Pointer setupPCB(char* nam, int pri, int cla){
	PCB_Pointer process = allocate_PCB();
	if(process == NULL){ return NULL;}
		else{
			if(findPCB(nam) != NULL){//see if the name is used yet
			removePCB(process);
			freePCB(process);
			printf("Process Name already taken, try again\n");
			return NULL;
		}
		strcpy(process->name, nam);//put nam into the mane of the process

		if(pri > UPPERPRI || pri < LOWERPRI){
		printf("Incorrect priority, must be between -128 to 127 try again\n");
			return NULL;
		}
		process->priority = pri;
		if(cla != SYSTEM && cla != APPLICATION){
			printf("Incorrect class designation, try again\n");
			return NULL;
		}
		process->clas = cla;
		process->stateR = READY;
		process->stateS = NOTSUSPEND;
		process->before = NULL;
		process->after = NULL;
		process->sTop = process->sBase + STACKSIZE - sizeof(context);
		
		return process;
	}//end if
}//end setupPCB	

/*
	Procedure:  createPCB
	Purpose: Creates the PCB
	Parameters:	char*
				char
	Return value: PCB_Pointer: pointer to the new PCB
	Calls: 	readHelp 
			setupPCB
			insertPCB
	Globals: none
	Errors: none
*/
PCB_Pointer createPCB(char* param, char arg){
	PCB_Pointer process;
	if (arg == '?') {	
		readHelp("create.txt");
	} else if (arg == '*') {
		
		char*  processName = NULL;
		char*  processClass = NULL;
		char*  processPriority = NULL;

		int intClass = 0;
		int intPri = 999;
		int i;

		
		//differentiate by white spaces
		processName = strtok(param," ");
		processClass = strtok(NULL, " ");
		processPriority = strtok(NULL, " ");

		if(processName==NULL || processClass == NULL || processPriority == NULL){ //too few arguments
			printf("Too few arguments in creation, try again'\n");
			return NULL;
		}
		if(strtok(NULL," ")!=NULL){	//if too many arguments
			printf("Too many arguments in creation, use format 'pName pClass pPri'\n");
			return NULL;
		}

		if(strlen(processName) > NAMESIZE){//if the name is too long
			printf("Process name too long, use a shorter name\n");
			return NULL;
		}

		if(!strnicmp(processClass,"app",3)){  //if  application
			intClass = APPLICATION;
		} else if(!strnicmp(processClass,"sys",3)){ //if system
			intClass = SYSTEM;
		} else{  //if not proper 
			printf("Too many arguments in creation, use format 'pName pClass pPri'\n");
			return NULL;
		}


		for(i=0;processPriority[i]!='\0';i++){
			   //	if(!isdigit(processPriority[i])&&!(i==0&&processPriority[i]=='-')){
			   //		printf("\nEnter decimal digits only\n");
			   //		return NULL;
			   //	}//end if
		}//end for
		intPri = atoi(processPriority);

		process = setupPCB(processName, intPri, intClass);
		if(process == NULL){
			printf("Process not created\n");
			return NULL;
		}

		insertPCB(process);
		return process;
	} else {
		int temp = 16;
		sys_req(WRITE, TERMINAL, "Unknown Argument", &temp);
	}
	return process;
}//end createPCB


/*
	Procedure:  deletePCB
	Purpose: Creates the PCB
	Parameters:	char* param: contains the filename
				char arg: determines whether to find the helpfile, or to run the command
	Return value: int: determines if successful
	Calls: 	readHelp 
			findPCB
			removePCB
			freePCB
	Globals: none
	Errors: none
*/
int deletePCB(char* param, char arg){
	if (arg == '?') {	
		readHelp("delete.txt");
	} else if (arg == '*') {
		int status;
		int size;
		char buf[80] = {'\0'};
		PCB_Pointer process;
		size=80;

		if(strlen(param) == 0){
			printf("Too few arguments, try again");
			return NULL;
		}//check if user really wants to delete pcb node
		printf("Are you sure you want to delete %s?\n", param);

		status = sys_req(READ, TERMINAL, buf, &size);

		if(status<0){
			printf("I/O error: %d\n", status);
		}//end check return code

		if(!strncmp(buf, "yes", 3)||!strncmp(buf,"y",1)){
			process = findPCB(param);
			if(process == NULL){
					printf("Process not found, try again\n");
					return NULL;
				}
				removePCB(process);
				freePCB(process);
				return 1;
		} else{
			return 1;
		}
	} else {
		int temp = 16;
		sys_req(WRITE, TERMINAL, "Unknown Argument", &temp);
	}
	return 1;
}//end deletePCB
	
	
/*
	Procedure:  blockPCB
	Purpose: Derived for user command "block"Puts the PCB into a blocked state, then places it into either BLocked equeue
	Parameters:	char* param: contains the filename
				char arg: determines whether to find the helpfile, or to run the command
	Return value: int: determines if successful
	Calls: 	insert
			removePCB
			readHelp	
	Globals: none
	Errors: none
*/
int blockPCB(char* param, char arg){
	if (arg == '?') {	
		readHelp("block.txt");
	} else if (arg == '*') {
		PCB_Pointer process;
		if(strlen(param) == 0){
			printf("Not enough Arguments, try again\n");
			return NULL;
		}

		process = findPCB(param);
		if(process == NULL){
			printf("Cannot find the process, try again\n");
			return NULL;
		}

		//check the stateR of the process
		if(process->stateR != BLOCKED){//if it is not currently blocked, put in block
			removePCB(process);
			process->stateR = BLOCKED;
			insert(&Blocked, process);
			return 1;
		}//end process is not already blocked

		else{//then it is alread blocked, put error
		printf("Process is already blocked\n");
			return NULL;
			
		}//end proccess is already blocked
	} else {
		int temp = 16;
		sys_req(WRITE, TERMINAL, "Unknown Argument", &temp);
	}
	return 1;
}//end blockPCB()
	

/*
	Procedure:  unblockPCB
	Purpose: Derived for user command "unblock" Puts the PCB into a unblocked state, then places it into ready queue
	Parameters:	char* param: contains the filename
				char arg: determines whether to find the helpfile, or to run the command
	Return value: int: determines if successful
	Calls: 	insertPCB
			removePCB
			readHelp	
	Globals: none
	Errors: none
*/
int unblockPCB(char* param, char arg){
	if (arg == '?') {	
		readHelp("unblock.txt");
	} else if (arg == '*') {
		PCB_Pointer process;
		if(strlen(param) == 0){
			printf("Not enough arguments, try again\n");
			return NULL;
		}

		process = findPCB(param);
		if(process == NULL){
			printf("Process not found, try again\n");
			return NULL;
		}//end if

		if(process->stateR == BLOCKED){//if stateR is currently blocked, unblock it
			removePCB(process);
			process->stateR = READY;
			insertPCB(process);

			return 1;
		}//end if

		else{//otherwise state is already blocked, return error
			printf("Process is already blocked, try again\n");
			return NULL;
		}//end else
	} else {
		int temp = 16;
		sys_req(WRITE, TERMINAL, "Unknown Argument", &temp);
	}
	return 1;
}//end unblockPCB


/*
	Procedure:  suspendPCB
	Purpose: Derived for user command "suspend" Puts the PCB into a suspended state, then places it into ready queue
	Parameters:	char* param: contains the filename
				char arg: determines whether to find the helpfile, or to run the command
	Return value: int: determines if successful
	Calls: 	insertPCB
			removePCB
			readHelp	
	Globals: none
	Errors: none
*/
int suspendPCB(char* param, char arg){
	if (arg == '?') {	
		readHelp("suspend.txt");
	} else if (arg == '*') {
		PCB_Pointer process;
		if(strlen(param) == 0){
			printf("Too few arguments, try again\n");
			return NULL;
		}//end if

		process = findPCB(param);
		if(process == NULL){
			printf("Process not found, try again\n");
			return NULL;
		}

		

		if(process->stateS != SUSPEND){//if stateS is not alreadt suspended
			removePCB(process);
			process->stateS = SUSPEND;
			insertPCB(process);
			return 1;
		}//end if
		if (process->clas == SYSTEM){
			printf("Process is a system process, suspend stopped\n");
			return NULL;
		}
		else{
			printf("Process is already suspended, try again\n");
			return NULL;
		}//end else
	} else {
		int temp = 16;
		sys_req(WRITE, TERMINAL, "Unknown Argument", &temp);
	}
	return 1;
}//end suspendPCB


/*
	Procedure:  resumePCB
	Purpose: Derived for user command "resume" Puts the PCB into a ready state, then places it into ready queue
	Parameters:	char* param: contains the filename
				char arg: determines whether to find the helpfile, or to run the command
	Return value: int: determines if successful
	Calls: 	insertPCB
			removePCB
			readHelp	
	Globals: none
	Errors: none
*/
int resumePCB(char* param, char arg){
	if (arg == '?') {	
		readHelp("resume.txt");
	} else if (arg == '*') {
		PCB_Pointer process;
		if(strlen(param) == 0){
			printf("Too few arguments, try again\n");
			return NULL;
		}//end if

		process = findPCB(param);
		if(process == NULL){
			printf("Process not found, try again\n");
			return NULL;
		}//end if

		if(process->stateS == SUSPEND){//if the process is suspended, reverse it
			removePCB(process);
			process->stateS = NOTSUSPEND;
			insertPCB(process);
			return 1;
		}//end if

		else{//process is already suspended
			printf("Process is already unsuspended, try again\n");
			return NULL;
		}//end else
	} else {
		int temp = 16;
		sys_req(WRITE, TERMINAL, "Unknown Argument", &temp);
	}
	return 1;
}//end resumePCB()


/*
	Procedure:  setPriorityPCB
	Purpose: Derived for user command "setPriority" Allows the user to set the priority of a process
	Parameters:	char* param: contains the filename
				char arg: determines whether to find the helpfile, or to run the command
	Return value: int: determines if successful
	Calls: 	insertPCB
			removePCB
			readHelp	
	Globals: none
	Errors: none
*/
int setPriorityPCB(char* param, char arg){
	if (arg == '?') {	
		readHelp("setpri.txt");
	} else if (arg == '*') {
		PCB_Pointer process;
		char listArgs[80];//list of arguments
		char* processName;
		char* priorityArg;
		int priorityInt;
		int i;

		strcpy(listArgs, param);//copy list of arguments into a new args for concatenation

		processName = strtok(listArgs," ");   //Get the first token from the listArgs
		priorityArg = strtok(NULL," ");      //Get the second token from the listArgs

		if(processName==NULL){	
			printf("Too few arguments, try again\n");
			return NULL;
		}//end if
		
		if(priorityArg==NULL){
			process = findPCB(processName);
			if(process == NULL){
				printf("Process not found, try again\n");
				return NULL;
			}
			printf("The current priority of process %s is %d.\n", processName, process->priority);
			return 1;
		}//end if
		if(strtok(NULL," ")!=NULL){
			printf("Too many arguments, try again\n");
			return NULL;
		}//end if

		process = findPCB(processName);
		if(process == NULL){
			printf("\nProcess not found, try again\n");
			return NULL;
		}//end if

		for(i=0;priorityArg[i]!='\0';i++){
			if(!isdigit(priorityArg[i])&&!(i==0&&priorityArg[i]=='-')){
				printf("Argument invalid, try again\n");
				return NULL;
			}//end if
		}//end for
		priorityInt = atoi(priorityArg);
		if(priorityInt>127 || priorityInt<-128){
			printf("Incorrect priority, choose from -128 to 127, try again\n");
			return NULL;
		}
		removePCB(process);
		process->priority = priorityInt;
		insertPCB(process);
		return 1;
	} else {
		int temp = 16;
		sys_req(WRITE, TERMINAL, "Unknown Argument", &temp);
	}
	return 1;
}


/*
	Procedure:  showPCB
	Purpose: Derived for user command "show" Shows the information about a specific PCB
	Parameters:	char* param: contains the filename
				char arg: determines whether to find the helpfile, or to run the command
	Return value: int: determines if successful
	Calls: 	readHelp	
	Globals: none
	Errors: none
*/
int showPCB(char* param, char arg){
	if (arg == '?') {	
		readHelp("show.txt");
	} else if (arg == '*') {
		PCB_Pointer process;
		char* state = "       ";
		char* classs;
		char* suspense;

		if(strlen(param) == 0){
					printf("Not Enough Arguments, try again\n");
					return NULL;
		}

		process = findPCB(param);
		if(process == NULL)
		{
					printf("Process cannot be found, try again\n");
					return NULL;
		}

		if(process->clas == SYSTEM)
					strcpy(classs,"System");
		else if(process->clas == APPLICATION)
					strcpy(classs, "Application");
		if(process->stateS == SUSPEND)
					strcpy(suspense, "Suspended");
		else if(process->stateS == NOTSUSPEND)
					strcpy(suspense, "");
			

		if(process->stateR == READY)
					strcpy(state, "Ready");
		else if(process->stateR == RUN)
					strcpy(state, "Running");
		else if(process->stateR == BLOCKED)
					strcpy(state, "Blocked");

	   printf("Name: %s \t State: %s %s \t Class:%s \t Priority: %d\n\n", process->name, state, suspense, classs, process->priority);

	   return 1;
	} else {
		int temp = 16;
		sys_req(WRITE, TERMINAL, "Unknown Argument", &temp);
	}
	return 1;
}


/*
	Procedure:  showQPCB
	Purpose: Derived for user command "showQueue" Shows all of the PCBs in a particular queue
	Parameters:	PCB_Pointer - Pointer to the correct PCB queue
	Return value: None
	Calls:  readHelp	
	Globals: none
	Errors: none
*/
void showQPCB(PCB_Pointer q){
    PCB_Pointer process;
    char state[80];
    char cl[80];
    char suspense[80];
	int page;
	
    process = q;
    while(process != NULL){//while not pointing at the end(NULL)
		if(page<15) {
			page = page + 1;
			if(process->clas == SYSTEM)
				strcpy(cl, "System     ");
			else if(process->clas == APPLICATION)
				strcpy(cl, "Application");

			if(process->stateS == SUSPEND)
				strcpy(suspense, "Suspended");
			else if(process->stateS == NOTSUSPEND)
			strcpy(suspense, "         ");

			if(process->stateR == READY)
				strcpy(state, "Ready  ");
			else if(process->stateR == RUN)
				strcpy(state, "Running");
			else if(process->stateR == BLOCKED)
				strcpy(state, "Blocked");
			printf("%s\t%s %s %s %d\n", process->name, state, cl, suspense, process->priority);
			process = process->after;//advance the pointer position 
		}//end if
		else {//pagination
				page = 0;
				char* PageNat = "\nPress any key to continue\n\0";
				size = strlen(PageNat);
				sys_req(WRITE, TERMINAL, PageNat, &size);
				//size = 1;
				sys_req(READ, TERMINAL, buf, &size);
				sys_free_mem(PageNat);
		}//end else
    }//end while
}//end showQPCB()


/*
	Procedure:  showAllPCB
	Purpose: Derived for user command "showAll" Shows all of the PCBs in all of the queues
	Parameters:	char* param: contains the filename
				char arg: determines whether to find the helpfile, or to run the command
	Return value: int: determines if successful
	Calls: 	showQPCB
			readHelp	
	Globals: none
	Errors: none
*/
int showAllPCB(char* param, char arg){
	if (arg == '?') {	
		readHelp("showall.txt");
		return NULL;
	} 
	else if (arg == '*'){
		if(strlen(param)!=0){
			printf("Too many Arguments, try again\n");
			return NULL;
		}//end if

		if(Ready != NULL || Blocked != NULL || Running != NULL || SuspReady != NULL || SuspBlocked != NULL){
			printf("Name: \t\t State & Class: \t Priority:\n");
		}
		else{
			printf("There are currently no processes available.\n");
			return NULL;
		}//end no processes available
		showQPCB(CurrOP);
		showQPCB(Running);
		showQPCB(Ready);
		showQPCB(Blocked);
		showQPCB(SuspReady);
		showQPCB(SuspBlocked);
		
		return 1;
	}else {
		int temp = 16;
		sys_req(WRITE, TERMINAL, "Unknown Argument", &temp);
		return NULL;
	}
}//end showAllPCB


/*
	Procedure:  showReadyPCB
	Purpose: Derived for user command "showReady" Shows the PCBs in the ready queue
	Parameters:	char* param: contains the filename
				char arg: determines whether to find the helpfile, or to run the command
	Return value: int: determines if successful
	Calls: 	showQPCB
			readHelp	
	Globals: none
	Errors: none
*/
int showReadyPCB(char* param, char arg){
	if (arg == '?') {	
		readHelp("sready.txt");
	} else if (arg == '*') {
		if(strlen(param)!=0){
			printf("There are currently no processes available.\n");
			return NULL;
		}
		if(Ready != NULL || SuspReady != NULL){//are the queues empty?
			printf("Name: \t State & Class: \t Priority:\n");
		}
		else{
			printf("There are currently no processes available.\n");
			return NULL;
		}
		showQPCB(Ready);
		showQPCB(SuspReady);
		return 1;
	} else {
		int temp = 16;
		sys_req(WRITE, TERMINAL, "Unknown Argument", &temp);
	}
	return 1;
}//end showReadyPCB


/*
	Procedure:  showBlockedPCB
	Purpose: Derived for user command "showBlocked" Shows the PCBs in the blocked queue
	Parameters:	char* param: contains the filename
				char arg: determines whether to find the helpfile, or to run the command
	Return value: int: determines if successful
	Calls: 	showQPCB
			readHelp	
	Globals: none
	Errors: none
*/
int showBlockedPCB(char* param, char arg){
	if (arg == '?') {	
		readHelp("sblocked.txt");
	} else if (arg == '*') {
		if(strlen(param)!=0){
				printf("Too many arguments, try again\n");
			return NULL;
		}

		if(Blocked != NULL || SuspBlocked != NULL){//if they're not empty
			printf("Name: \t State & Class: \t Priority:\n");
		}

		else{
			printf("There are currently no processes available.\n");
		}//end no processes available

			showQPCB(Blocked);
			showQPCB(SuspBlocked);
		return 1;
	} else {
		int temp = 16;
		sys_req(WRITE, TERMINAL, "Unknown Argument", &temp);
	}
	return 1;
}//end showBLockedPCB

/*
	Procedure:  getQueuePTR
	Purpose: Pulling queue pointers to other modules
	Parameters:	int num - Which queue pointer shold be returned
	Return value: PCB_Pointer: pointer to the queue
	Calls: 	none	
	Globals: 	CurrOP
				Ready
				Blocked
				SuspReady
				SuspBlocked
	Errors: none
*/
PCB_Pointer getQueuePTR(int num){// function to pull queue pointers through to other Modules
	PCB_Pointer thereturn;
	switch(num){
		case 0:
			thereturn = CurrOP;
			break;
		case 1:
			thereturn = Ready;
			break;
		case 2:
			thereturn = Blocked;
			break;	
		case 3:
			thereturn = SuspReady;
			break;
		case 4:
			thereturn = SuspBlocked;
			break;
		default:
			thereturn = NULL;
			break;
	}//end switch
	return thereturn;
}//getQueuePTR	


/*
	Procedure:  deleteAllPCB
	Purpose: Derived for user command "deleteAll" Deletes all PCBs in all queues
	Parameters:	none
	Return value: int: determines if successful
	Calls: 	deletePCB2	
	Globals: none
	Errors: none
*/
int deleteAllPCB(){
    PCB_Pointer currentNode;
    PCB_Pointer nextNode;
    currentNode = Ready;
    while(currentNode!=NULL){
        nextNode = currentNode->after;
        deletePCB2(currentNode);
        currentNode = nextNode;
    }
    currentNode = Blocked;
    while(currentNode!=NULL){
        nextNode = currentNode->after;
        deletePCB2(currentNode);
        currentNode = nextNode;
    }
    currentNode = SuspBlocked;
    while(currentNode!=NULL){
        nextNode = currentNode->after;
        deletePCB2(currentNode);
        currentNode = nextNode;
    }
    currentNode = SuspReady;
    while(currentNode!=NULL){
        nextNode = currentNode->after;
        deletePCB2(currentNode);
        currentNode = nextNode;
    }
    currentNode = CurrOP;
    while(currentNode!=NULL){
        nextNode = currentNode->after;
        deletePCB2(currentNode);
        currentNode = nextNode;
    }
    return 1;
}

/*
	Procedure:  deletePCB2
	Purpose: Remove and free the memory for a PCB
	Parameters:	PCB_Pointer pre - Pointer to the PCB
	Return value: int: determines if successful
	Calls: 	removePCB
			freePCB
	Globals: none
	Errors: none
*/
int deletePCB2(PCB_Pointer pre){
	removePCB(pre);
	freePCB(pre);
	return 1;	
}//end deletePCB

/*
	Procedure:  createPCB2
	Purpose: Quick way to make a new PCB
	Parameters:	char* processName: Name of the process to be created
				int intClass: Integer value of the class the PCB should be "app or sys"
				int intPri: Priority of the PCB
	Return value: PCB_Pointer: pointer to the new PCB
	Calls: 	insertPCB	
	Globals: none
	Errors: none
*/
PCB_Pointer createPCB2(char* processName, int intClass, int intPri ){
	PCB_Pointer process;

	    
	if(strlen(processName) > NAMESIZE){//if the name is too long
		printf("Process name too long, use a shorter name\n");
		return NULL;
	}
	process = setupPCB(processName, intPri, intClass);
	if(process == NULL){
		printf("process not created\n");
		return NULL;
	}
	insertPCB(process);
	return process;

}//end createPCB2
